package org.noka.tree;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.noka.gson.Gson;
import org.noka.gson.reflect.TypeToken;
import org.nokatag.password.AESPlus;
import org.nokatag.system.BugInfoWrint;
import org.nokatag.system.Concest;
import org.nokatag.system.DBCon;
import org.nokatag.system.Function;
import org.nokatag.system.NLoadFun;
import org.nokatag.system.PreparedParemSet;
import org.nokatag.system.RunUserFunction;
import org.nokatag.system.ServletNokaContext;

public class TreeData {
	public  void getData(HttpServletRequest request,HttpServletResponse response,FilterConfig config){
		String body=null;
		try{
			response.setContentType("text/json");
			String sql = request.getParameter("sql");//加密数据
			if(null!=sql){
				sql=AESPlus.decrypt(sql.trim(),Concest.SQLKEY);//解密sql
			}
			String d = request.getParameter("do");//操作模式 1为节点,2为取下关联节点id
			String spid= request.getParameter("pid");//上级id
			String level= request.getParameter("le");//level,为4时，该参数为多个id
			String nodes= request.getParameter("nodes");//节点json数据
			String formatcell= request.getParameter("fc");//加密数据
			String url= request.getParameter("url");//加密数据
			String uf= request.getParameter("uf");//节点移动调用的方法
			String pramevar= request.getParameter("pr");//加密数据
			String target= request.getParameter("tar");
			//--------------------------------------------------------
			if("1".equals(d) || "2".equals(d)){//获取节点数据
				formatcell=(formatcell==null?null:AESPlus.decrypt(formatcell,Concest.SQLKEY));
				url=(url==null?null:AESPlus.decrypt(url,Concest.SQLKEY));
				pramevar=(pramevar==null?null:AESPlus.decrypt(pramevar,Concest.SQLKEY));
				body=getRootNodes(spid,sql,formatcell,url,pramevar,target,request);
			}else if("3".equals(d)){//获取该级节点下所有的节点id
				body=getNexIds(level,sql,request);//当获取下级所有节点时，spid为lvie数据，形如:1_2
			}else if("4".equals(d)){
				body=getNodes(level,sql,request);
			}else if("5".equals(d)){//更新数据
				if(null!=uf){
					uf = AESPlus.decrypt(uf,Concest.SQLKEY);//解密
					if(uf.toLowerCase().startsWith("update")){//sql
						body=MoveNode(uf,nodes);
					}else{
						body=MoveNodeUF(uf,nodes);
					}
				}
			}else if("6".equals(d)){//获取当前节点及所有上级节点
				body=getPNodes(spid,sql,request);
			}
			OutputStream out = response.getOutputStream();
			Writer wr=new OutputStreamWriter(out,Concest.ENCODING);
			if(body!=null){
				wr.write(body);
				wr.flush();
				out.flush();
				wr.close();
				out.close();
			}
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}
	}
	/**
	 * sql修改node
	 * @param id
	 * @param pid
	 * @param level
	 * @param olevel
	 * @return
	 */
	private String MoveNode(String sql,String nodes) {
		StringBuffer body = new StringBuffer();
		Connection con = ServletNokaContext.getConnection();
		try{
			Gson gson = new Gson();
			List<Map<String,String>> nodeList = gson.fromJson(nodes,new TypeToken<List<Map<String,String>>>(){}.getType());
			try{
				con.setAutoCommit(false);
				PreparedStatement msta = con.prepareStatement(sql);//"UPDATE nk_sys_treebook set tpid =? ,TLVIE=? WHERE tid =?"
				for(Map<String,String> m:nodeList){
					msta.setLong(1,Long.parseLong(m.get("pid")));
					msta.setString(2,m.get("leve"));
					msta.setLong(3,Long.parseLong(m.get("id")));
					msta.addBatch();
				}
				msta.executeBatch();
				con.commit();//提交事务
				msta.close();
				con.setAutoCommit(true);
			}catch(Exception se){
				con.rollback();//回滚事务
			}
			body.append("{\"code\":true,\"msg\":\"\"}");
			return body.toString();
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}
		body.append("{\"code\":false,\"msg\":\"update false\"}");
		return body.toString();
	}
	private String MoveNodeUF(String path,String nodes){
		try {
			NLoadFun nloadFun = new NLoadFun();
			NTreeMoveNode action = (NTreeMoveNode)nloadFun.getBean(path);
			return action.MoveNode(path,nodes);
		} catch (Exception e) {
			BugInfoWrint.Print("noka connection is : " + "file:"+ Concest.ROOTDIR + "/WEB-INF/classes" + " " + path);
		}
		return "{\"code\":false}";
	}
	
	/**
	 * 获取根节点及一级节点数据
	 * @param request
	 * @return
	 */
	private String getRootNodes(String spid,String sql,String formatcell,String url,String pramevar,String target,HttpServletRequest request){
		StringBuffer body = new StringBuffer();
		Connection con = DBCon.getCon();
		try{
			con.setAutoCommit(true);
			//-------------找出root节点-------------------------------------------------
			String min_sql="SELECT * FROM ("+sql+") TEMP WHERE PID = (SELECT MIN(PID) AS PID FROM("+sql+") TEMPS)";
			if(spid!=null && spid.trim().length()>0)
				min_sql="SELECT * FROM("+sql+") TEMPS WHERE PID=?";
			BugInfoWrint.Print(min_sql);
			PreparedStatement msta = con.prepareStatement(min_sql);
			if(spid!=null && spid.trim().length()>0){
				msta.setLong(1,Long.parseLong(spid));
			}
			ResultSet min_rst =msta.executeQuery();
			ResultSetMetaData rsmd = min_rst.getMetaData();
			body.append("[");
			while(min_rst.next()){
				String id=min_rst.getString("id");
				String pid=min_rst.getString("pid");
				String name=jsonForm(min_rst.getString("name"));
				String title=jsonForm(min_rst.getString("title"));
				String level=min_rst.getString("leve");
				//---------------自定义格式化列---------------------------------------------
				if(formatcell!=null && formatcell.trim().length()>0){
					for(String fun:formatcell.split("\\|")){
						String cn = fun.substring(fun.indexOf(" as ")+" as ".length(),fun.length());
						fun=fun.split(" as ")[0];
						String v=RunUserFunction.TagFunction(fun, request, min_rst);
						if(cn.equals("name")){
							name=v;
						}else if(cn.equals("title")){
							title=v;
						}
					}
				}
				//----------------url参数解析------------------------------------------------
				String urls="javascript:void(0);";//默认url没有处理
				if(Function.TableFieldIsExit(rsmd, "url")){
					String ur = min_rst.getString("url");
					if(ur!=null)
						urls=ur;
				}
				if(urls.startsWith("javascript") && url!=null)
					urls=url;
				String pramevars = pramevar;
				if(pramevar!=null && pramevar.trim().length()>0){
			        for(int i=1;i<=rsmd.getColumnCount();i++){
			        	try{
			        		pramevars = pramevars.replaceAll("(?i)\\$\\["+rsmd.getColumnName(i)+"\\]", min_rst.getString(rsmd.getColumnName(i)));
			        	}catch(Exception se){}
			        }
			        if(urls.indexOf("?")==-1){
			        	urls+="?&"+pramevars;
			        }else{
			        	urls+="&"+pramevars+"&";
			        }
			    }
				//-------------target解析---------------------------------------------------
				String targets="_self";
				if(Function.TableFieldIsExit(rsmd, "target")){
					String ta = min_rst.getString("target");
					if(ta!=null)
						targets=ta;
				}
				if(targets.startsWith("_self") && target!=null)
					targets=target;
				//----------组织返回数据------------------------------------------
				body.append("{");
				body.append("id:'"+id+"',");
				body.append("pid:'"+pid+"',");
				body.append("name:'"+name+"',");
				body.append("title:'"+title+"',");
				body.append("url:'"+urls+"',");
				body.append("subnode:true,");
				body.append("level:'"+level+"',");
				body.append("target:'"+targets+"',");
				//----------自定义属性-------------------------------------------
				body.append("cnode:{");
				for(int i=1;i<=rsmd.getColumnCount();i++){
		        	try{
		        		body.append(rsmd.getColumnName(i).toLowerCase()+":'"+jsonForm(min_rst.getString(rsmd.getColumnName(i)))+"',");
		        	}catch(Exception se){}
		        }
				if(body.toString().endsWith(","))
					body.delete(body.length()-1, body.length());
				body.append("}");
				//--------------------------------------------------------------
				body.append("},");
			}
			if(body.length()>3)
				body.delete(body.length()-1, body.length());
			body.append("]");
			min_rst.close();
			msta.close();
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}
		return body.toString();
	}
	/**
	 * 获取下级所有id
	 * @param spid
	 * @param sql
	 * @param request
	 * @return
	 */
	private String getNexIds(String lvie,String sql,HttpServletRequest request){
		StringBuffer body = new StringBuffer();
		Connection con = DBCon.getCon();
		try{
			con.setAutoCommit(true);
			String min_sql="select id from("+sql+") temp where leve like ?";
			PreparedStatement msta = con.prepareStatement(min_sql);
			msta.setString(1, lvie+"%");
			ResultSet min_rst =msta.executeQuery();
			StringBuffer bd = new StringBuffer();
			StringBuffer sbd = new StringBuffer();
			while(min_rst.next()){
				String idv = min_rst.getString(1);
				bd.append("'"+idv+"',");
				sbd.append(idv+",");
			}
			if(bd.length()>1)
				bd.delete(bd.length()-1, bd.length());
			if(sbd.length()>1)
				sbd.delete(sbd.length()-1, sbd.length());
			body.append("{");
			body.append("str:'"+sbd.toString()+"',");
			body.append("ids:["+bd.toString()+"]");//[1,3,4,]
			body.append("}");
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}
		return body.toString();
	}
	/**
	 * 根据id获取节点数据
	 * @param ids
	 * @param sql
	 * @param request
	 * @return
	 */
	private String getNodes(String ids,String sql,HttpServletRequest request){
		StringBuffer body = new StringBuffer();
		Connection con = DBCon.getCon();
		try{
			con.setAutoCommit(true);
			if(ids==null){
				body.append("{");
				body.append("nodes:[");	
				body.append("],");
				body.append("nstr:''");
				body.append("}");
				return body.toString();
			}
			String[] nd = ids.split(",");//1,3,4
			String wd = "";
			for(int i=0;i<nd.length;i++){
				wd+=",?";
			}
			if(wd.startsWith(","))//,?,?,?
				wd=wd.substring(1);
			String min_sql="select * from("+sql+") temp where id in("+wd+")";
			PreparedStatement msta = con.prepareStatement(min_sql);
			for(int i=0;i<nd.length;i++){
				msta.setLong(i+1,Long.parseLong(nd[i]));
			}
			ResultSet min_rst =msta.executeQuery();
			StringBuffer bd = new StringBuffer();
			body.append("{");
			body.append("nodes:[");
			while(min_rst.next()){
				String id=min_rst.getString("id");
				String pid=min_rst.getString("pid");
				String name=jsonForm(min_rst.getString("name"));
				String title=jsonForm(min_rst.getString("title"));
				String level=min_rst.getString("leve");
				body.append("{");
				body.append("id:'"+id+"',");
				body.append("pid:'"+pid+"',");
				body.append("name:'"+name+"',");
				body.append("title:'"+title+"',");
				body.append("level:'"+level+"'");
				body.append("},");
				bd.append(name+",");
			}
			if(body.length()>1)
				body.delete(body.length()-1, body.length());
			if(bd.length()>1)
				bd.delete(bd.length()-1, bd.length());
			body.append("],");
			body.append("nstr:'"+bd.toString()+"'");
			body.append("}");
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}
		return body.toString();
	}
	/**
	 * <p>@Description 获取本级节点及上级节点</p>
	 * <p>author rebin </p>
	 * <p>@Time 下午4:41:32</p>
	 * <p>xiefangjian@163.com</p>
	 * @param ids
	 * @param sql
	 * @param request
	 * @return
	 */
	private String getPNodes(String ids,String sql,HttpServletRequest request){
		StringBuffer body = new StringBuffer();
		Connection con = DBCon.getCon();
		PreparedStatement msta = null;
		PreparedStatement msta2=null;
		ResultSet min_rst = null;
		ResultSet min_rst2 = null;
		try{
			con.setAutoCommit(true);
			if(ids==null){
				body.append("{");
				body.append("nodes:[");	
				body.append("],");
				body.append("nstr:''");
				body.append("}");
				return body.toString();
			}
			String[] nd = ids.split(",");//1,3,4
			String wd = "";
			for(int i=0;i<nd.length;i++){
				wd+=",?";
			}
			if(wd.startsWith(","))//,?,?,?
				wd=wd.substring(1);
			//String wd = " ? ";
			//--------------------根据id获取当前节点的leve数据--------------------------
			String min_sql="select * from("+sql+") temp where id in("+wd+")";
			msta = con.prepareStatement(min_sql);
			for(int i=0;i<nd.length;i++){
				msta.setLong(i+1, Long.parseLong(nd[i]));
			}
			min_rst =msta.executeQuery();
			List<String> level = new ArrayList<String>();
			while(min_rst.next()){
				level.add(min_rst.getString("leve"));//0_-1_1_2
			}
			//--------------------遍历深度---------------------------------------------
			Long maxLeng = 0L;
			try{
				String titllev = request.getParameter("titllev");
				if(null!=titllev){
					maxLeng= Long.parseLong(titllev);
				}
			}catch(Exception se){}
			Long spid = null;
			try{
				String spids = request.getParameter("spid");
				if(null!=spids){
					spid= Long.parseLong(spids);
				}
			}catch(Exception se){}
			//---------------------获取所有父级----------------------------------------
			if(null!=level && !level.isEmpty()){
				body.append("[");
				for(int a=0;a<level.size();a++){
					String le = level.get(a);
					String[] leves = le.split("_");
					maxLeng=((maxLeng>-1 && maxLeng<=leves.length)?maxLeng:leves.length);
					String lwd ="? ";
					for(int i=0;i<maxLeng;i++){
						lwd +=",?";
					}
					String min_sql2="select * from("+sql+") temp where id in("+lwd+")  "+(null!=spid?" and id <> "+spid+"":"")+"  ORDER BY leve asc";
					msta2 = con.prepareStatement(min_sql2);
					msta2.setLong(1,Long.parseLong(ids.split(",")[a]));
					Integer indx = 2;
					for(int i=leves.length-1;(indx-1)<=maxLeng;i--){
						msta2.setLong(indx,Long.parseLong(leves[i]));
						indx++;
					}
					min_rst2 =msta2.executeQuery();
					//-------------------------------------------------------------------
					StringBuffer bd = new StringBuffer();
					body.append("{");
					body.append("nodes:[");
					while(min_rst2.next()){
						String id=min_rst2.getString("id");
						String pid=min_rst2.getString("pid");
						String name=jsonForm(min_rst2.getString("name"));
						String title=jsonForm(min_rst2.getString("title"));
						String plevel=min_rst2.getString("leve");
						body.append("{");
						body.append("id:'"+id+"',");
						body.append("pid:'"+pid+"',");
						body.append("name:'"+name+"',");
						body.append("title:'"+title+"',");
						body.append("level:'"+plevel+"'");
						body.append("},");
						bd.append(name+"-");
					}
					if(body.length()>1)
						body.delete(body.length()-1, body.length());
					if(bd.length()>1 && bd.toString().endsWith("-"))
						bd.delete(bd.length()-1, bd.length());
					body.append("],");
					body.append("nstr:'"+bd.toString()+"'");
					body.append("},");
				}
				if(body.length()>1)
					body.delete(body.length()-1, body.length());
				body.append("]");
			}else{
				body.append("{");
				body.append("nodes:[");	
				body.append("],");
				body.append("nstr:''");
				body.append("}");
				return body.toString();
			}
		}catch(Exception se){
			BugInfoWrint.Print(se);
		}finally{
			
		}
		return body.toString();
	}
	//-----------------------------设置参数--------------------------------------------------------------
	protected void setPares(PreparedStatement pa,Integer indx,Object o,int types) throws SQLException{
			PreparedParemSet pset = new PreparedParemSet();
			pset.setPre(pa,indx,o,types);
	}
	public String jsonForm(String va){
		return va=(va==null?"":va.replace("\'","\\'").replace("\r","\\r").replace("\n","\\n").replace("\t","\\t"));
	}
}
